' This program exported from BASIC Anywhere Machine (Version [5.2.3].[2024.09.09.00.00]) on 2026.02.07 at 19:07 (Coordinated Universal Time)
' This program is a port and mod of "Aizawa Attactor" QB64pe program by Kurt Moerman
' shared with the "BASIC Programming Language" Facebook group in the following post:
' https://www.facebook.com/share/p/18QjzP3kHn/
Option _Explicit
DIM countdown%
DIM Nstore = 5000 ' number of data points stored for drawing
DIM Nloop = 4000 ' extra iterations for accuracy (keep dt small)
Const T = 40 ' Total time interval covered
Const a = 0.95 'Aizawa Attractor parameters
Const b = 0.7
Const c = 0.6
Const d = 3.5
Const e = 0.25
Const f = 0.1
' graphing parameters
Const margin = 30 ' margin between window edges and drawing
Const yzangle = 45 * _Pi / 180 ' angle over which graph is rotated around x axis
Const xyangle = 20 * _Pi / 180 ' angle over which graph is rotated around z axis
Const dscr = 30 ' distance eyeball to projection screen
Const dxyz = 45 ' distance eyeball to xyz axes origin
Dim As Long c1, c2, co
Dim As Integer pr, pg, pb, r
Dim As Double x, xsq, y, z, dx_dt, dy_dt, dz_dt, dt
Dim As Single xscr(Nstore), yscr(Nstore), cos_yzangle, sin_yzangle, cos_xyangle, sin_xyangle
Dim As Single xscrmax, yscrmax, xscrmin, yscrmin, xscrscale, yscrscale, yr, zr, xr, yr2
DIM d% = 650
DIM aco% = 0 ' INT( RND * 3 + 1 )
Screen _NewImage( d%, d%, 32 )
_Title "Aizawa Attractor"
🔶StartGraph:
cos_yzangle = Cos(yzangle): sin_yzangle = Sin(yzangle) ' calc values once, use many times
cos_xyangle = Cos(xyangle): sin_xyangle = Sin(xyangle)
dt = T / (Nstore * Nloop) ' time step for Euler Method
For r = 1 To 20 ' several runs each with different init. values and plot color
x = Rnd * 0.1: y = 0: z = 0.05 ' initial values with some randomness
IF r = 1 OR INT(RND * aco% + 1 ) = 1 THEN
🎨some_other_color:
pr = INT( RND * 256 )
pg = INT( RND * 256 )
pb = INT( RND * 256 )
IF pr + pg + pb < 100 THEN GOTO 🎨some_other_color
END IF
co = _RGB32(pr, pg, pb) ' convert r,g,b into 32 bit color value
For c1 = 0 To Nstore - 1
' rotate 3D coord. around x axis to tilt graph for viewing
' |cos -sin| |x| rotation matrix
' |sin cos| |y|
yr = y * cos_yzangle - z * sin_yzangle
zr = y * sin_yzangle + z * cos_yzangle
' rotate 3D coord. around z axis to tilt graph for viewing
xr = x * cos_xyangle - yr * sin_xyangle
yr2 = x * sin_xyangle + yr * cos_xyangle
'calculate and store projected coordinates: 3D to 2D
xscr(c1) = xr * dscr / (dxyz + yr2)
yscr(c1) = zr * dscr / (dxyz + yr2)
' keep track of max and min values
xscrmin = Min(xscrmin, xscr(c1))
xscrmax = Max(xscrmax, xscr(c1))
yscrmin = Min(yscrmin, yscr(c1))
yscrmax = Max(yscrmax, yscr(c1))
' extra interations to keep errors low from Euler method (smaller dt)
For c2 = 0 To Nloop - 1
xsq = x * x
dx_dt = (z - b) * x - d * y ' three ODEs of the Aizawa Attractor
dy_dt = d * x + (z - b) * y
dz_dt = c + a * z - z * z * z / 3.0 - (xsq + y * y) * (1 + e * z) + f * z * x * xsq
x = dx_dt * dt + x: y = dy_dt * dt + y: z = dz_dt * dt + z ' Euler method
Next c2
Next c1
xscrscale = (XMAX - 2 * margin) / (xscrmax - xscrmin) ' avoid calculating these each time
yscrscale = (yMAX - 2 * margin) / (yscrmax - yscrmin)
For c1 = 0 To Nstore - 1 ' scale and draw xscr,ysxr array values
xscr(c1) = margin + (xscr(c1) - xscrmin) * xscrscale ' scale coord. to screen window
yscr(c1) = margin + (yscrmax - yscr(c1)) * yscrscale
PSet (xscr(c1), yscr(c1)), co
IF c1 MOD 21 = 0 THEN sleep 0.001
Next c1
Next r
FOR countdown% = 10 TO 1 step - 1
locate 1,1 : PRINT countdown% + " "
sleep 1
NEXT t%
Nstore = INT( RND * 10 + 1 ) * 500 ' number of data points stored for drawing
Nloop = INT( RND * 1000 + 1 ) * 4
d% = INT( RND * 8 + 3) * 100
aco% = 1 + RND * 9
Screen _NewImage( d%, d%, 32 )
GOTO 🔶StartGraph